Before an image can be rendered by a computer graphics system, it must first be modeled in a format that the computer can utilize. Modeling techniques and tools describe a virtual environment with primitives that can be rendered by the graphics hardware. Primitives are basic geometric shapes such as polygons, cubic patches or surfaces, and so forth. These primitives can be stretched and rotated into any position, thus allowing the construction of complex forms.
Regardless of the method used to model the virtual environment, the graphics hardware (or software) must convert the modeled primitives into an array of frame buffer pixels that can be drawn on a display device. This process of converting modeled primitives into visible pixels is known as rendering.
An important part of the rendering process is known as hidden surface removal. Hidden surface removal determines which primitives in the scene should be visible for any given pixel (or sub-pixel if anti-aliasing techniques are employed). Common hidden-surface-removal techniques include the painter's algorithm, list-priority algorithms, scan line algorithms, and Z buffering, which is also known as depth buffering.
Each of the hidden-surface removal techniques has distinct advantages and disadvantages. For various reasons, the depth buffer has now become a popular choice. Most of the other approaches require special modeling strategies and support structures in order to render the image properly. The depth buffer approach eliminates many of these constraints, thereby simplifying the modeling process. With a depth buffer, the visible surface at each pixel (or sub-pixel) is simply the primitive with the closest depth value for each pixel. As each primitive is rendered, this depth parameter is computed for each pixel touched. Along with storing the color of each pixel, a frame buffer can be expanded to also store the depth value. As each new primitive is processed, the new depth is compared with the one already in the frame buffer. The frame buffer then simply keeps whichever primitive is closest to the observer.
The depth buffer technique tends to break down for primitives that are coincident with each other. A primitive is considered to be coincident if it has substantially the same depth as another primitive, such as a stripe on a road or a door on a side of a building. Limited computing precision when specifying the position of primitives relative to one another makes it mathematically difficult to consistently compute which surface is on top. Various techniques have been developed to assist the depth buffer to correctly select which primitive is closer to the view point. These techniques include depth value scale/offset, reference planes, stencil buffer, etc. Each of these techniques complicates the basic depth buffer algorithm in some way. Most place restrictions on the rendering process such as handling the primitives in a specific order (fix-listing) or requiring additional information to accompany the primitives.
In most rendering architectures, hidden surface removal is now accomplished using a depth buffer. For each pixel (or sub-pixel) in the scene, the depth buffer compares the depths of each primitive that touches it and keeps the one that is closest. The basic depth buffer consists of a simple comparison between an incoming pixel's depth value and the value already stored in the depth buffer. The incoming pixel's address within the 2-dimensional array of pixels stored in the frame buffer is used to select which depth is compared with the incoming depth.
Many techniques have been developed to augment this simple test when it is unable to correctly resolve the ordering between two coincident primitives. Each of these techniques is based on two assumptions. First, the assumption that the modeler must specify the correct visual priority order of coincident primitives. Since the order can't be computed, it must be defined. Second, the rendering process must correctly interpret and enforce that defined order.
The simpler methods adjust the primitive's depth value such that it is forced in front or behind another primitive based on its modeled priority. This adjustment is usually a simple scale or offset of the depth value to exaggerate its position. This technique, however, is not very consistent. Adjustment values that work correctly for some primitives in the scene may not adjust other primitives far enough to be correctly resolved. In addition, other primitives in the scene may be moved too far and move in front of scene elements they are supposed to be behind.
Stencil buffering is a technique that provides a second value besides depth that can be independently stored and tested in conjunction with the depth test. A “stencil” value can be assigned to “child” primitives that lie on top of “parent” primitives. In frame buffer locations where the parent primitive can win the regular depth test, it can also mark the stencil buffer with its unique “stencil” value. The child primitive is able to be placed on top of the parent primitive where it belongs due to the associated stencil value stored in the frame buffer.
While this technique is useful, it relies on the primitives being rendered in a fixed order to correctly resolve the visual priority. There are also restrictions relative to the management of the stencil buffer such that multiple different coincident groups within the scene do not conflict.
In addition, most of these coincident primitive extensions are not completely compatible with advanced depth reduction techniques in use. For instance, the techniques may require rendering the primitives in a back-to-front order. Others require all of the pixels of all of the primitives to be rendered. This incompatibility reduces or eliminates the benefits associated with these advanced techniques when coincident primitives are rendered.